//DMX�������ģ�飬DMXʱ�ӹ̶�Ϊ2M��
module dmx_ack	(
		input	wire		sclk,
		input	wire		resetb,
		
		input	wire		t_us,
		
		//DMX信号分频数
		input	wire	[9:0]	div_count_max,	//150M��Ƶʱ��
		
		//DMX接收控制
		input	wire		mem_read_start,	//接收起始
		input	wire	[3:0]	mem_active_port,//接收端口选择
		input	wire	[7:0]	dmx_ack_in,	//接收数据
		
		//总线读取控制
		input	wire	[15:0]	ext_addr,
		input	wire	[15:0]	set_addr,
		output	reg	[7:0]	dmx_ack_data,
		output	reg	[7:0]	dmx_state_data,
		
		//调试输出
		output	wire	[31:0]	tout	
		);

wire		dmx_sync;
wire	[7:0]	dmx_data;
reg	[2:0]	err_port_num_r,active_port;
reg	[6:0]	start_read;
reg	[10:0]	data_count;
reg		dmx_ack_flag;
reg	[15:0]	bad_p_num,total_p_num;
reg		dmx_rec_reset;

reg	[4:0]	dmx_ack_waddr;
reg	[7:0]	dmx_ack_wdata;
reg		dmx_ack_wen;

reg		state_r_active,ack_r_active;
wire	[7:0]	dmx_ack_rdata,dmx_state_rdata;
//parameter	ADD_COUNT	=1;			//1
//parameter	GET_MAX_DATA	=ADD_COUNT+2;		//3
//parameter	SET_ZERO	=GET_MAX_DATA+2;	//5

parameter	BAD_P_START	=6;
parameter	TOTAL_P_START	=8;

wire	[31:0]	ddd_tout;

assign	tout = ddd_tout;

//接收启动信号
always @(posedge sclk or negedge resetb)
	if(resetb==0)
		start_read <= 0;
	else
		start_read <= {start_read[5:0],mem_read_start};

always @(posedge sclk)
	active_port <= mem_active_port - 1;

always@(posedge sclk)
	dmx_rec_reset<=	start_read[2];

//DMX接收解码
dmx_none_space_rx	dmx_rx	(
			.sclk(sclk),
			.resetb(resetb),

			.div_count_max(div_count_max),

			.t_us(t_us),
			.dmx_rec_reset(dmx_rec_reset),
			
			.dmx_ack_in(dmx_ack_in),
			.active_port(active_port),	
			
			.dmx_sync(dmx_sync),
			.dmx_data(dmx_data),
			
			.tout(ddd_tout)
			);

//***************DMX读取控制********************
always	@(posedge sclk)
	if(ext_addr == 16'h0 && set_addr[15:8] == 8'h0)
		state_r_active <= 1;
	else
		state_r_active <= 0;
	
always	@(posedge sclk)
	if(ext_addr == 16'h20A1)
		ack_r_active <= 1;
	else
		ack_r_active <= 0;

always	@(posedge sclk)
	if(state_r_active == 0)
		dmx_state_data <= 0;
	else
		dmx_state_data <= dmx_state_rdata;
	
always	@(posedge sclk)
	if(ack_r_active == 0)
		dmx_ack_data <= 0;
	else
		dmx_ack_data <= dmx_ack_rdata;
	
////////////////mix ram//////////////////
///��DMX ʵʱ��� ��DMX �� RAM�ռ� �ϲ�
reg             wen_a;
reg     [7:0]   data_a;
reg     [9:0]   addr_a;
 
reg             wen_b;
reg     [7:0]   data_b;
reg     [9:0]   addr_b;
              
sram_1k8i_tdp mix_table(
	.address_a(addr_a),
	.address_b(addr_b),
	.clock(sclk),
	.data_a(data_a),
	.data_b(data_b),
	.wren_a(wen_a),
	.wren_b(wen_b),
	.q_a(dmx_ack_rdata),
	.q_b(dmx_state_rdata));   


always	@(posedge sclk)
	wen_a<=dmx_sync;

always	@(posedge sclk)
	if(dmx_sync==1)
		addr_a<={1'b1,1'b0,data_count[7:0]};
	else
		addr_a<={1'b1,1'b0,set_addr[7:0]};
		
always	@(posedge sclk)	
	data_a<=dmx_data;

always	@(posedge sclk)
       	if(dmx_ack_wen==1)
                wen_b<=1'b1;
        else
                wen_b<=0;
                
always	@(posedge sclk)
        if(dmx_ack_wen)
                addr_b<={1'h0,4'h0,dmx_ack_waddr};
        else
                addr_b<={1'h0,4'h0,set_addr[7:0]};                

always	@(posedge sclk)
                data_b<=dmx_ack_wdata;   
                

/////////��MEM����///////////////
//wire		data_wea;
//wire	[7:0]	data_addra,data_addrb;
//wire	[7:0]	data_dina,data_doutb;
//
//swsr_256w8_256r8 read_mem_buf(
//			.wrclock(sclk),
//			.wren(data_wea),
//			.wraddress(data_addra),
//			.data(data_dina),
//			.rdclock(sclk),
//			.rdaddress(data_addrb),
//			.q(data_doutb)	
//			);
//
//assign	data_wea	=dmx_sync;
//assign	data_addra	=data_count;
//assign	data_dina	=dmx_data;
//
//assign	data_addrb	=(mcu_mem_active==1)?state_addr:0;
//assign	state_data	=data_doutb;
////////////////////////////


always @(posedge sclk or negedge resetb)
	if(resetb==0)
		data_count<=0;
	else if(mem_read_start==1)
		data_count<=0;
	else if(dmx_sync==1)
		data_count<=data_count+1;


always @(posedge sclk or negedge resetb)
	if(resetb==0)
		dmx_ack_flag<=0;
	else if(mem_read_start==1)
		dmx_ack_flag<=0;
	else if(data_count==0 && dmx_sync==1 && dmx_data==8'ha5)
		dmx_ack_flag<=1;

always @(posedge sclk or negedge resetb)
	if(resetb==0)
	begin
		bad_p_num<=0;
		total_p_num<=0;
	end
	else if(start_read[6:5]==2'b10)
	begin
		bad_p_num<=0;
		total_p_num<=0;
	end
	else if(dmx_ack_flag==1 && dmx_sync==1)
	begin
		case(data_count)
			BAD_P_START	:bad_p_num[7:0]		<=dmx_data;
			BAD_P_START+1	:bad_p_num[15:8]	<=dmx_data;
			TOTAL_P_START	:total_p_num[7:0]	<=dmx_data;
			TOTAL_P_START+1	:total_p_num[15:8]	<=dmx_data;
		endcase		
	end

always@(posedge sclk or negedge resetb)
	if(resetb==0)
		dmx_ack_wen<=0;
	else if(start_read[2:1]==2'b10)
		dmx_ack_wen<=1;
	else if(start_read[6:5]==2'b10)
		dmx_ack_wen<=0;

wire	[2:0]	pre_port;
assign	pre_port=active_port-1;

always@(posedge sclk or negedge resetb)
	if(resetb==0)
		dmx_ack_waddr<=0;
	else if(dmx_ack_wen==0)
		dmx_ack_waddr<={pre_port[2:0],2'b00};
	else
		dmx_ack_waddr<=dmx_ack_waddr+1;

always@(posedge sclk or negedge resetb)
	if(resetb==0)
		dmx_ack_wdata<=0;
	else if(start_read[2:1]==2'b10)
		dmx_ack_wdata<=total_p_num[7:0];
	else if(start_read[3:2]==2'b10)
		dmx_ack_wdata<=total_p_num[15:8];
	else if(start_read[4:3]==2'b10)
		dmx_ack_wdata<=bad_p_num[7:0];
	else if(start_read[5:4]==2'b10)
		dmx_ack_wdata<=bad_p_num[15:8];

endmodule
		